package ar.uba.fi.taller2.cmmiassistant.frontend.reportes;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeCellRenderer;

import ar.uba.fi.taller2.cmmiassistant.controlador.Controlador;
import ar.uba.fi.taller2.cmmiassistant.controlador.Transicion;
import ar.uba.fi.taller2.cmmiassistant.frontend.PanelVista;
import ar.uba.fi.taller2.cmmiassistant.frontend.adaptadores.arbol.NodoArbol;
import ar.uba.fi.taller2.cmmiassistant.frontend.renderers.CmmiAssistantTreeCellRenderer;
import ar.uba.fi.taller2.cmmiassistant.vista.Accion;
import ar.uba.fi.taller2.cmmiassistant.vista.Estado;
import ar.uba.fi.taller2.cmmiassistant.vista.Vista;

public class PanelReportes extends PanelVista {

	private static final long serialVersionUID = 5026077125079228195L;
	private ArbolReportes arbolReportes;
	private CardLayout layoutPanel;
	/**
	 * Manejador de eventos de seleccion sobre el arbol.
	 */
	private TreeSelectionListener observadorSeleccion = new TreeSelectionListener() {

		public void valueChanged(TreeSelectionEvent evento) {

			/* obtiene el nodo seleccionado */
			NodoArbol nodo = (NodoArbol) evento.getPath()
					.getLastPathComponent();

			/* si el nodo tiene una transicion asociada la ejecuta */
			Transicion transicion = nodo.getAlSeleccionar();

			if (transicion != null) {

				PanelReportes.this.getControlador().ejecutar(transicion);
			}
		}
	};
	private JPanel panel;
	private JPanel panelVacio;
	private List<ReporteEvaluacion> reportes = new LinkedList<ReporteEvaluacion>();

	private JScrollPane scrollPane;

	private JSplitPane splitPane;
	private JTree treeNavegacion;
	private JPanel panelReporte;
	private JPanel panelSelectorReporte;
	private JComboBox comboBoxReportes;
	private ActionListener observadorComboBox = new ActionListener() {

		public void actionPerformed(ActionEvent e) {
			ReporteEvaluacion reporteEvaluacion = (ReporteEvaluacion) comboBoxReportes
					.getSelectedItem();
			Transicion transicion = new Transicion(PanelReportes.this,
					reporteEvaluacion);
			PanelReportes.this.getControlador().ejecutar(transicion);
		}

	};
    private TreeCellRenderer cellRenderer;

	public PanelReportes(Vista contexto) {
		super(contexto);
		initialize();
	}

	private ArbolReportes getArbolReportes() {

		if (this.arbolReportes == null) {

			this.arbolReportes = new ArbolReportes();
			this.arbolReportes.setVista(this);
		}
		return arbolReportes;
	}

	@Override
	public Estado getEstado() {
		return Estado.VISUALIZANDO_REPORTES;
	}

	private CardLayout getLayoutPanel() {

		if (this.layoutPanel == null) {

			this.layoutPanel = new CardLayout();
		}

		return this.layoutPanel;
	}

	/**
	 * This method initializes panel
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getPanel() {
		if (panel == null) {
			panel = new JPanel();
			panel.setLayout(new BorderLayout());
			panel.setBorder(new EmptyBorder(3, 3, 3, 3));
			panel.add(getPanelSelectorReporte(), BorderLayout.NORTH);
			panel.add(getPanelReporte(), BorderLayout.CENTER);

		}
		return panel;
	}

	private JPanel getPanelReporte() {
		if (panelReporte == null) {
			panelReporte = new JPanel();
			panelReporte.setLayout(getLayoutPanel());
			/* panel vacio */
			panelReporte.add(this.getPanelVacio(), "");

			for (ReporteEvaluacion reporteEvaluacion : reportes) {
				panelReporte.add(reporteEvaluacion, reporteEvaluacion
						.getEstado().getName());
			}

		}

		return panelReporte;
	}

	private JPanel getPanelSelectorReporte() {
		if (panelSelectorReporte == null) {
			panelSelectorReporte = new JPanel();
			panelSelectorReporte.setLayout(new BoxLayout(panelSelectorReporte,
					BoxLayout.X_AXIS));
			panelSelectorReporte.add(new JLabel("Reporte:"));
			panelSelectorReporte.add(getComboBoxReportes());
		}

		return panelSelectorReporte;
	}

	private JComboBox getComboBoxReportes() {
		if (comboBoxReportes == null) {
			DefaultComboBoxModel comboBoxModel = new DefaultComboBoxModel();
			comboBoxReportes = new JComboBox(comboBoxModel);
			for (ReporteEvaluacion reporteEvaluacion : reportes) {
				comboBoxModel.addElement(reporteEvaluacion);
			}
			comboBoxReportes.addActionListener(this.observadorComboBox);
		}
		return comboBoxReportes;
	}

	private JPanel getPanelVacio() {

		if (this.panelVacio == null) {
			this.panelVacio = new JPanel();
		}
		return this.panelVacio;
	}

	/**
	 * This method initializes scrollPane
	 * 
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getScrollPane() {
		if (scrollPane == null) {
			scrollPane = new JScrollPane();
			scrollPane.setMinimumSize(new Dimension(200, 200));
			scrollPane.setViewportView(getTreeNavegacion());
		}
		return scrollPane;
	}

	/**
	 * This method initializes splitPane
	 * 
	 * @return javax.swing.JSplitPane
	 */
	private JSplitPane getSplitPane() {
		if (splitPane == null) {
			splitPane = new JSplitPane();
			splitPane.setLeftComponent(getScrollPane());
			splitPane.setRightComponent(getPanel());
		}
		return splitPane;
	}

	/**
	 * This method initializes treeNavegacion
	 * 
	 * @return javax.swing.JTree
	 */
	private JTree getTreeNavegacion() {
		if (treeNavegacion == null) {
			treeNavegacion = new JTree();
			treeNavegacion.addTreeSelectionListener(this.observadorSeleccion);
			treeNavegacion.setModel(this.getArbolReportes());
			treeNavegacion.setCellRenderer(this.getCellRenderer());
		}
		return treeNavegacion;
	}

	private TreeCellRenderer getCellRenderer() {

	    if (this.cellRenderer == null) {
	        
	        this.cellRenderer = new CmmiAssistantTreeCellRenderer();
	    }
        return this.cellRenderer;
    }

    private void inicializarReportes() {
		reportes.add(new ReporteNivelesAlcanzadosEscalonada(this));
		reportes.add(new ReporteNivelesAlcanzadosContinua(this));
		reportes.add(new ReporteCoberturaEvidencia(this));
		for (ReporteEvaluacion reporteEvaluacion : reportes) {
			configurarAlActivar(reporteEvaluacion);
		}
	}

	private void initialize() {
		inicializarReportes();
		this.setLayout(new BorderLayout());
		this.setSize(new Dimension(425, 290));
		this.add(getSplitPane(), BorderLayout.CENTER);

	}

	public void setControlador(Controlador controlador) {

		super.setControlador(controlador);
		this.getArbolReportes().setControlador(controlador);
		for (ReporteEvaluacion reporteEvaluacion : reportes) {
			reporteEvaluacion.setControlador(controlador);
		}
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				comboBoxReportes.setSelectedIndex(0);
			}
		});

	}

	private void configurarAlActivar(final ReporteEvaluacion reporteEvaluacion) {

		reporteEvaluacion.setAlActivar(new Accion() {

			public void ejecutar(Vista vista) {
				PanelReportes.this.getLayoutPanel().show(getPanelReporte(),
						reporteEvaluacion.getEstado().getName());
			}
		});
	}
}
